package com.mossle.core.hibernate; import java.util.ArrayList; import java.util.Collection; import java.util.List; import java.util.Locale; import java.util.regex.Matcher; import java.util.regex.Pattern; import com.mossle.core.query.MatchType; import com.mossle.core.query.PropertyFilter; import com.mossle.core.util.BeanUtils; import org.hibernate.Criteria; import org.hibernate.Query; import org.hibernate.criterion.CriteriaSpecification; import org.hibernate.criterion.Criterion; import org.hibernate.criterion.Disjunction; import org.hibernate.criterion.MatchMode; import org.hibernate.criterion.Projection; import org.hibernate.criterion.Restrictions; import org.hibernate.internal.CriteriaImpl; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.util.Assert; /** * hibernate utils. * * @author Lingo */ public class HibernateUtils { /** logger. */ private static Logger logger = LoggerFactory .getLogger(HibernateUtils.class); /** protected constructor. */ protected HibernateUtils() { } /** * get number for count. * * @param result * Object * @return Integer */ public static Integer getNumber(Object result) { if (result == null) { return 0; } else { return ((Number) result).intValue(); } } /** * 去除hql的select 子句,未考虑union的情况,用于pagedQuery. * * @param hql * HQL字符串 * @return 删除select语句后的字符串 * @see HibernatePagingDao#pagedQuery(String,int,int,Object[]) */ public static String removeSelect(String hql) { Assert.hasText(hql); if (hql.toLowerCase(Locale.ENGLISH).indexOf("distinct") != -1) { logger.warn( "there is a distinct in paged query hql : [{}], this maybe cause an unexpected result", hql); } int beginPos = hql.toLowerCase(Locale.CHINA).indexOf("from"); Assert.isTrue(beginPos != -1, " hql : " + hql + " must has a keyword 'from'"); return hql.substring(beginPos); } /** * 去除hql的order by 子句,用于pagedQuery. * * @param hql * HQL字符串 * @return 删除排序语句后的字符串 * @see HibernatePagingDao#pagedQuery(String,int,int,Object[]) */ public static String removeOrders(String hql) { Assert.hasText(hql); Pattern p = Pattern.compile("order\\s*by[\\w|\\W|\\s|\\S]*", Pattern.CASE_INSENSITIVE); Matcher m = p.matcher(hql); StringBuffer sb = new StringBuffer(); while (m.find()) { m.appendReplacement(sb, ""); } m.appendTail(sb); return sb.toString(); } /** * distinct. * * @param query * Query * @return Query */ public static Query distinct(Query query) { query.setResultTransformer(CriteriaSpecification.DISTINCT_ROOT_ENTITY); return query; } /** * distinct. * * @param criteria * Criteria * @return Criteria */ public static Criteria distinct(Criteria criteria) { criteria.setResultTransformer(CriteriaSpecification.DISTINCT_ROOT_ENTITY); return criteria; } /** * find projection from criteria. * * @param criteria * Criteria * @return Projection */ public static Projection findProjection(Criteria criteria) { if (criteria instanceof CriteriaImpl) { return ((CriteriaImpl) criteria).getProjection(); } else { throw new IllegalArgumentException(criteria + " is not a CriteriaImpl"); } } /** * find order entries. * * @param criteria * Criteria * @return List */ public static List findOrderEntries(Criteria criteria) { return (List) BeanUtils.safeGetFieldValue(criteria, "orderEntries"); } /** * set order entries. * * @param criteria * Criteria * @param orderEntries * List */ public static void setOrderEntries(Criteria criteria, List orderEntries) { BeanUtils.safeSetFieldValue(criteria, "orderEntries", orderEntries); } /** * 按属性条件参数创建Criterion,辅助函数. * * @param propertyName * String * @param propertyValue * Object * @param matchType * MatchType * @return Criterion */ public static Criterion buildCriterion(String propertyName, Object propertyValue, MatchType matchType) { Assert.hasText(propertyName, "propertyName不能为空"); Criterion criterion = null; // 根据MatchType构造criterion switch (matchType) { case EQ: criterion = Restrictions.eq(propertyName, propertyValue); break; case NOT: criterion = Restrictions.ne(propertyName, propertyValue); break; case LIKE: criterion = Restrictions.like(propertyName, (String) propertyValue, MatchMode.ANYWHERE); break; case LE: criterion = Restrictions.le(propertyName, propertyValue); break; case LT: criterion = Restrictions.lt(propertyName, propertyValue); break; case GE: criterion = Restrictions.ge(propertyName, propertyValue); break; case GT: criterion = Restrictions.gt(propertyName, propertyValue); break; case IN: criterion = Restrictions.in(propertyName, (Collection) propertyValue); break; case INL: criterion = Restrictions.isNull(propertyName); break; case NNL: criterion = Restrictions.isNotNull(propertyName); break; default: criterion = Restrictions.eq(propertyName, propertyValue); break; } return criterion; } /** * 按属性条件列表创建Criterion数组,辅助函数. * * @param filters * List * @return Criterion[] */ public static Criterion[] buildCriterion(List<PropertyFilter> filters) { List<Criterion> criterionList = new ArrayList<Criterion>(); for (PropertyFilter filter : filters) { // 只有一个属性需要比较的情况. if (!filter.hasMultiProperties()) { Criterion criterion = buildCriterion(filter.getPropertyName(), filter.getMatchValue(), filter.getMatchType()); criterionList.add(criterion); } else { // 包含多个属性需要比较的情况,进行or处理. Disjunction disjunction = Restrictions.disjunction(); for (String param : filter.getPropertyNames()) { Criterion criterion = buildCriterion(param, filter.getMatchValue(), filter.getMatchType()); disjunction.add(criterion); } criterionList.add(disjunction); } } return criterionList.toArray(new Criterion[criterionList.size()]); } public static void buildQuery(StringBuilder buff, PropertyFilter propertyFilter) { if (buff.toString().toLowerCase().indexOf("where") == -1) { buff.append(" where "); } else { buff.append(" and "); } buff.append(propertyFilter.getPropertyName()); switch (propertyFilter.getMatchType()) { case EQ: buff.append("=:"); break; case NOT: buff.append("<>:"); break; case LIKE: buff.append(" LIKE:"); break; case LE: buff.append("<=:"); break; case LT: buff.append("<:"); break; case GE: buff.append(">=:"); break; case GT: buff.append(">:"); break; case IN: buff.append("IN :"); break; case INL: buff.append(" IS NULL"); break; case NNL: buff.append(" IS NOT NULL"); break; default: buff.append("=:"); break; } buff.append(propertyFilter.getPropertyName().replaceAll("\\.", "_")); } }